﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Decal;

/*my FAVORITE kind of black magic*/
/*This include is probably not necessary, but it's fair warning for what's ahead.*/
using System.Reflection;

using Decal.Adapter;
using Decal.Adapter.Wrappers;

namespace InspectorGadget
{
    public static class Globals
    {
        private static string m_plugin_name;
        public static string plugin_name
        {
            get { return m_plugin_name; }
            set { m_plugin_name = value; }
        }

        private static PluginHost m_host;
        public static PluginHost host
        {
            get { return m_host; }
            set { m_host = value; }
        }

        public static CoreManager m_core;
        public static CoreManager core
        {
            get { return m_core; }
            set { m_core = value; }
        }

        /// <summary>
        /// Output full names in the shallow inspection routines
        /// </summary>
        public static bool UseFullNames = false;

        /// <summary>
        /// Run a shallow inspection of an object. This assumes the type info is already posted.
        /// </summary>
        /// <param name="o">The object to inspect.</param>
        /// <param name="sb">The stringbuilder to append the results to</param>
        public static void ShallowInspect(object o, StringBuilder sb)
        {
            Type t = o.GetType(); 
            FieldInfo[] fields = t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);
            sb.Append("  Fields:").Append(Environment.NewLine);
            foreach(FieldInfo f in fields)
            {
                sb.Append("    ").Append(f.Name).Append(": ");                
                if(f.IsPublic) sb.Append("public ");
                if(f.IsPrivate) sb.Append("private ");
                if(!(f.IsPublic | f.IsPrivate)) sb.Append("protected ");
                if(f.IsStatic) sb.Append("static ");
                if(f.IsLiteral) sb.Append("readonly ");
                if(UseFullNames) sb.Append(f.FieldType.FullName);
                else sb.Append(f.ReflectedType.Name);
                sb.Append(Environment.NewLine);
                try //this may be blocked for private members...
                {
                    sb.Append("      ").Append(f.GetValue(o).ToString());
                }
                catch(Exception e)
                {
                    sb.Append("      Could not read value:").Append(e.Message);
                }
                sb.Append(Environment.NewLine);
            }

            PropertyInfo[] props = t.GetProperties();
            sb.Append("  Properties:").Append(Environment.NewLine);
            foreach(PropertyInfo p in props)
            {
                sb.Append("    ").Append(p.Name).Append(": ");
                if(p.CanRead) sb.Append("get; ");
                if(p.CanWrite) sb.Append("set; ");
                if(UseFullNames) sb.Append(p.PropertyType.FullName);
                else sb.Append(p.PropertyType.Name);
                sb.Append(Environment.NewLine);
                try //this may be blocked for private members...
                {
                    sb.Append("      ").Append(p.GetValue(o, null));
                }
                catch(Exception e)
                {
                    sb.Append("      Could not read value:").Append(e.Message);
                }
                sb.Append(Environment.NewLine);
            }
        }
    }
}
